package com.exam.demo.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.log.Log;
import cn.hutool.poi.excel.ExcelReader;
import cn.hutool.poi.excel.ExcelUtil;
import cn.hutool.poi.excel.ExcelWriter;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.exam.demo.common.Constants;
import com.exam.demo.common.Result;
import com.exam.demo.controller.dto.UserDTO;
import com.exam.demo.entity.Menu;
import com.exam.demo.entity.Student;
import com.exam.demo.entity.Student;
import com.exam.demo.exception.ServiceException;
import com.exam.demo.mapper.RoleMapper;
import com.exam.demo.mapper.RoleMenuMapper;
import com.exam.demo.mapper.StudentMapper;
import com.exam.demo.service.MenuService;
import com.exam.demo.service.RoleService;
import com.exam.demo.service.StudentService;
import com.exam.demo.util.NameMap;
import com.exam.demo.util.ObjectMapper;
import com.exam.demo.util.TokenUtils;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.net.URLEncoder;
import java.util.*;
/**
 * 功能描述
 *
 * @author yxj30
 * @date 2022/03/16  19:29
 */
@Service
public class StudentServiceImpl extends ServiceImpl<StudentMapper, Student> implements StudentService {

    private static final Log LOG = Log.get();

    @Resource
    StudentMapper studentMapper;

    @Resource
    RoleMapper roleMapper;

    @Resource
    RoleMenuMapper roleMenuMapper;

    @Resource
    MenuService menuService;

    @Resource
    RoleService roleService;


    @Override
    public Page<Student> findPage(Page<Student> page, String studentName) {
        return studentMapper.findPage(page,studentName);
    }
    public List<Student> findPage(String studentName) {
        return studentMapper.findPage(studentName);
    }

    @Override
    public HttpServletResponse export(HttpServletResponse response,String studentName) throws IOException {
        // 从数据库查询出所有的数据
        List<Student> list = findPage(studentName);//studentService.list
        System.out.println(list);
        // 通过工具类创建writer 写出到磁盘路径
//        ExcelWriter writer = ExcelUtil.getWriter(filesUploadPath + "/用户信息.xlsx");
        // 在内存操作，写出到浏览器
        ExcelWriter writer = ExcelUtil.getWriter(true);

        //重点： 自定义标题别名
        Map<String, String> nameMap = NameMap.getStudentNameMap();
        Set<String> keySet = nameMap.keySet();
        Iterator<String> iterator = keySet.iterator();
        while (iterator.hasNext()) {
            String key = iterator.next();
            writer.addHeaderAlias(key, nameMap.get(key));
        }
        // 一次性写出list内的对象到excel，使用默认样式，强制输出标题
        writer.write(list, true);

        // 设置浏览器响应的格式
        response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8");
        String fileName = URLEncoder.encode("学生信息", "UTF-8");
        response.setHeader("Content-Disposition", "attachment;filename=" + fileName + ".xlsx");

        ServletOutputStream out = response.getOutputStream();
        writer.flush(out, true);
        out.close();
        writer.close();
        return response;
    }

    /**
     * 导入数据库
     *
     * @param file
     * @return
     */
    @Override
    public boolean imp(MultipartFile file) throws IOException {
        InputStream inputStream = file.getInputStream();
        ExcelReader reader = ExcelUtil.getReader(inputStream);
        //1.读取xlsx数据
        List<Map<String, Object>> readAll = reader.readAll();

        //2.替换表头
        Map<String, String> nameMap = NameMap.getStudentNameMap();
        List<Student> students = new LinkedList<>();//存储替换后的student
        for (Map studentMap :
                readAll) {
            Iterator<Map.Entry<String, Object>> iterator = studentMap.entrySet().iterator();
            Map<String, Object> newStudentMap = new LinkedHashMap<>();
            while (iterator.hasNext()) {
                Map.Entry<String, Object> entry = iterator.next();
                String key = NameMap.getKey(nameMap, entry.getKey());
                if(key == null){
                    return false;
                }
                if (key == "id") {
                    newStudentMap.put(key, null);
                } else {
                    newStudentMap.put(key, entry.getValue());
                }
            }
            System.out.println(newStudentMap);
            Student student = JSON.parseObject(JSON.toJSONString(newStudentMap), Student.class);
            students.add(student);
        }
        System.out.println(students);
        //3.批量插入数据
        boolean b = saveBatch(students);
        return b;
    }

    @Override
    public UserDTO login(Student student) {
        Student one = getStudentInfo(student);
        if (one != null) {
            BeanUtil.copyProperties(one, student, true);//把one复制给student
            UserDTO user = ObjectMapper.studentToUserDTO(student); //把student转为userDTO
            // 设置token
            String token = TokenUtils.genToken(one.getStudentId(), one.getStudentPassword());
            user.setToken(token);
            user.setRole(Constants.ROLE_STUDENT);
            // 设置用户的菜单列表
            List<Menu> roleMenus = roleService.getRoleMenus(Constants.ROLE_STUDENT);
            user.setMenus(roleMenus);
            return user;
        } else {
            throw new ServiceException(Constants.CODE_600, "用户名或密码错误");
        }
    }


    private Student getStudentInfo(Student student) {
        QueryWrapper<Student> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("student_id",student.getStudentId());
        queryWrapper.eq("student_password",student.getStudentPassword());
        Student one;
        try {
            one = getOne(queryWrapper); // 从数据库查询用户信息
        } catch (Exception e) {
            LOG.error(e);
            throw new ServiceException(Constants.CODE_500, "系统错误");
        }
        return one;
    }




}
